/**
 * SKU表格生成工具
 * 根据规格选项动态生成SKU表格数据
 */

/**
 * 生成SKU表格数据
 * @param {Array} specOptions - 规格选项数组
 * @param {Array} existingSkuList - 已存在的SKU列表数据（可选）
 * @returns {Object} - 包含表头、行头和SKU数据的对象
 */
export const generateSkuTable = (specOptions, existingSkuList = []) => {
  // 如果规格选项为空，返回空数据
  if (!specOptions || specOptions.length === 0) {
    return {
      headers: [],
      data: [],
    }
  }

  // 提取已选择的规格值
  const selectedSpecs = specOptions
    .map((spec) => {
      return {
        id: spec.id,
        name: spec.name,
        values: spec.values.filter(
          (value) => value.selected || existingSkuList.length > 0
        ),
      }
    })
    .filter((spec) => spec.values.length > 0)

  // 如果没有选择任何规格值，返回空数据
  if (selectedSpecs.length === 0) {
    return {
      headers: [],
      data: [],
    }
  }

  // 生成表头
  const headers = selectedSpecs.map((spec) => ({
    prop: spec.name,
    label: spec.name,
    width: '150',
  }))

  // 添加价格、库存等自定义列
  headers.push(
    { prop: 'price', label: '价格', width: '120' },
    { prop: 'stock', label: '库存', width: '120' }
  )

  // 生成笛卡尔积
  const cartesian = (arr) => {
    return arr.reduce(
      (a, b) => {
        return a.flatMap((x) => b.map((y) => [...x, y]))
      },
      [[]]
    )
  }

  // 获取每个规格的所有可选值
  const specValueArrays = selectedSpecs.map((spec) => spec.values)

  // 生成所有可能的SKU组合
  let combinations = []

  if (specValueArrays.length > 0) {
    combinations = cartesian(specValueArrays)
  }

  // 构建最终的SKU数据表
  const skuData = combinations.map((combination) => {
    // 创建一个新的SKU对象
    const skuItem = {}

    // 填充规格值
    combination.forEach((value, index) => {
      skuItem[selectedSpecs[index].name] = value.name
    })

    // 查找现有SKU数据中是否有匹配的项
    const existingSku = findMatchingSku(skuItem, existingSkuList, selectedSpecs)

    // 如果有匹配的现有SKU，复用其价格和库存等信息
    if (existingSku) {
      skuItem.price = existingSku.price || '0'
      skuItem.stock = existingSku.stock || '0'
    } else {
      // 否则使用默认值
      skuItem.price = '0'
      skuItem.stock = '0'
    }

    // 生成唯一ID
    skuItem.id = generateSkuId(combination)

    return skuItem
  })

  return {
    headers,
    data: skuData,
  }
}

/**
 * 查找匹配的现有SKU
 * @param {Object} newSku - 新生成的SKU对象
 * @param {Array} existingSkuList - 现有的SKU列表
 * @param {Array} selectedSpecs - 已选择的规格
 * @returns {Object|null} - 匹配的SKU或null
 */
const findMatchingSku = (newSku, existingSkuList, selectedSpecs) => {
  if (!existingSkuList || existingSkuList.length === 0) {
    return null
  }

  // 查找所有规格值都匹配的SKU
  return existingSkuList.find((sku) => {
    return selectedSpecs.every((spec) => {
      // 考虑不同的属性命名方式
      const specName = spec.name.toLowerCase()
      const modelMatch =
        specName === 'model' || specName === '型号'
          ? sku.model === newSku[spec.name]
          : true

      const lengthMatch =
        specName === 'length' || specName === '长度'
          ? sku.length === newSku[spec.name]
          : true

      // 可以添加更多的规格类型匹配

      return modelMatch && lengthMatch
    })
  })
}

/**
 * 根据规格组合生成唯一的SKU ID
 * @param {Array} combination - 规格值组合
 * @returns {string} - 唯一ID
 */
const generateSkuId = (combination) => {
  return combination.map((item) => `${item.p_id || item.id}`).join('-')
}

/**
 * 从原始数据中提取规格值
 * @param {Array} skuList - SKU列表
 * @returns {Array} - 提取出的规格选项
 */
export const extractSpecsFromSkuList = (skuList) => {
  if (!skuList || skuList.length === 0) {
    return []
  }

  // 收集所有可能的属性作为规格
  const specsMap = {}

  // 遍历SKU列表以提取规格及其值
  skuList.forEach((sku) => {
    Object.keys(sku).forEach((key) => {
      // 排除一些不是规格的属性
      if (['id', 'price', 'stock', 'image'].includes(key)) {
        return
      }

      if (!specsMap[key]) {
        specsMap[key] = new Set()
      }

      if (sku[key]) {
        specsMap[key].add(sku[key])
      }
    })
  })

  // 转换为规格选项格式
  let specId = 1
  let valueId = 1

  return Object.keys(specsMap).map((key) => {
    const values = Array.from(specsMap[key]).map((value) => ({
      p_id: valueId++,
      name: value,
      selected: true,
    }))

    return {
      id: specId++,
      name: key,
      values,
    }
  })
}
